<?php
namespace App\Http\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Console\Router\Module;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Request;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Contract\MiddlewareInterface;
use Swoft\Redis\Redis;

/**
 * Class ApiCatchMiddleware
 * @package App\Http\Middleware
 * @Bean("ApiCatchMiddleware")
 */
class ApiCatchMiddleware implements MiddlewareInterface
{

    /**
     * 缓存时间
     * 默认 3600 秒
     * @var int
     */
    private $catchTime = 3600;

    /**
     * @inheritDoc
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 获取请求数据
        $requestData = $request->input();
        // 获取缓存 Key
        $catchKey = getCatchKey($requestData);
        // 如果开启了数据缓存 则检测是否有缓存数据 如果有直接返回缓存
        if (constant(Module::DEFINE_ENABLE_API_DATA_CATCH)) {

            if (Redis::exists($catchKey)) {
                $catchData = Redis::get($catchKey);
                return context()->getResponse()->withContentType(ContentType::JSON)->withData(json_decode($catchData, true));
            }
        }

        /** @var Response $Response */
        $Response = $handler->handle($request);
        // 获取接口返回数据
        $data = $Response->getData();
        // 开启API数据缓存
        if (constant(Module::DEFINE_ENABLE_API_DATA_CATCH)) {
            // 检测是否有缓存指令
            if (isset($data['catch']) && $data['catch'] == true) {
                $catchTime = $data['catch_time'] ?? $this->catchTime;
                Redis::setex($catchKey, (int)$catchTime, json_encode($data));
            }
        }

        //做下文件下载返回
        if((isset($data['result']['isFile']) && $data['result']['isFile'] === 1) || (isset($data['isFile']) && $data['isFile'] === 1)){
            $headers = $data['result']['headers']??$data['headers'];
            $fileData = $data['result']['fileData']??$data['fileData'];
            //导出文件
            // Do send file
            foreach ($headers as $item){
                $middle = explode(':', $item);
                $Response->getCoResponse()->header($middle[0], $middle[1], false);
            }

            return $Response->getCoResponse()->write(base64_decode($fileData));
        }

        return $Response->withContentType(ContentType::JSON)->withData($data);
    }

}
